package org.dromara.business.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.business.domain.Goods;
import org.dromara.business.service.BusinessConfigService;
import org.dromara.business.service.GoodsService;
import org.dromara.business.service.UserFlowingService;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.web.core.BaseController;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysUserService;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * vip
 *
 * @author zlj
 * @date 2024-08-01
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/vip")
public class VipController extends BaseController {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    private final String USER_SIGN_KEY = "sign:";
    private final BusinessConfigService configService;
    private final UserFlowingService userFlowingService;
    private final ISysUserService userService;
    private final GoodsService goodsService;

    /**
     * 签到接口
     */
    @GetMapping("/sign")
    @RepeatSubmit()
    public R<Void> sign() {
        //生成key
        String key = this.getKey();
        //获取本月第几天
        int dayOfMonth = DateUtil.dayOfMonth(DateUtils.getNowDate());
        //判断今日是否签到
        //查询redis
        List<Long> result = stringRedisTemplate.opsForValue().bitField(key,
            BitFieldSubCommands.create()
                .get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0));
        if ((result.get(0) & 1) == 1) {
            throw new ServiceException("今日已签到");
        }
        //存到redis
        stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);
        //增加积分
        String points = configService.queryValueByKey("points");
        // userFlowingService.addAmount(LoginHelper.getUserId(), Integer.valueOf(points), BusinessConstants.FLOWING_TYPE_SIGN, null);
        return R.ok();
    }

    /**
     * 判断今天是否打卡
     */
    @GetMapping("/getTodayIsSign")
    public R<Boolean> getTodayIsSign() {
        //生成key
        String key = this.getKey();
        //获取本月第几天
        int dayOfMonth = DateUtil.dayOfMonth(DateUtils.getNowDate());
        //查询redis
        List<Long> result = stringRedisTemplate.opsForValue().bitField(key,
            BitFieldSubCommands.create()
                .get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0));
        return R.ok((result.get(0) & 1) == 1);
    }

    /**
     * 老用户绑定邀请人
     */
    @GetMapping("/bindSuperior")
    public R<Void> bindSuperior(Long userId) {
        Long id = LoginHelper.getUserId();
        SysUser me = userService.getById(id);
        //已有上级,不做处理
        if (ObjectUtil.isNotNull(me.getSuperiorId())) {
            return R.ok();
        }

        //不能绑定自己的下级
        boolean isDown = userService.isDown(userId);
        if (isDown) {
            return R.ok();
        }
        //没有上级,绑定上级
        me.setSuperiorId(userId);
        userService.updateById(me);
        return R.ok();
    }
    private String getKey() {
        Long userId = LoginHelper.getUserId();
        Date nowDate = DateUtils.getNowDate();
        String keySuffix = DateUtil.format(nowDate, ":yyyyMM");
        return USER_SIGN_KEY + userId + keySuffix;
    }

    /**
     * 修改用户头像昵称信息
     *
     * @return 用户信息
     */
    @PostMapping("/updateWxInfo")
    @Transactional(rollbackFor = Exception.class)
    public R<Void> updateWxInfo(String nickName, String avatar) {
        Long userId = LoginHelper.getUserId();
        userService.lambdaUpdate()
            .set(StrUtil.isNotBlank(nickName), SysUser::getNickName, nickName)
            .set(StrUtil.isNotBlank(avatar), SysUser::getWxAvatar, avatar)
            .eq(SysUser::getUserId, userId)
            .update();
        goodsService.lambdaUpdate().set(Goods::getUserProfile, avatar).eq(Goods::getCreateBy, userId).update();
        return R.ok();
    }

    @RepeatSubmit(interval = 1000, message = "正在获取定位,请稍后")
    @GetMapping("/getAddress")
    public R<String> getAddress(@RequestParam String location) {
        String key = configService.queryValueByKey("map");
        Map<String, Object> param = new HashMap<>();
        param.put("key", key);
        param.put("location", location);
        String response = HttpUtil.get("https://apis.map.qq.com/ws/geocoder/v1/", param);
        JSONObject result = JSONUtil.parseObj(response);
        Integer status = result.getInt("status");
        if (ObjectUtil.notEqual(status, 0)) {
            log.error("解析地址错误: 错误码: " + status + ", 错误信息: " + result.getStr("message"));
            throw new ServiceException("解析地址错误, 请联系管理员");
        }
        return R.data(result.getJSONObject("result").getStr("address"));
    }

    /**
     * 查询团队
     */
    @GetMapping("/getMyTeam")
    public R<Map<String, Object>> getMyTeam(PageQuery query) {
        Map<String, Object> map = new HashMap<>();
        //查询团队业绩
//        SysUser user = userService.getById(LoginHelper.getUserId());
//        map.put("teamAmount", "");
        //查询团队
        IPage<SysUser> page = userService.lambdaQuery().eq(SysUser::getSuperiorId, LoginHelper.getUserId()).page(query.build());
        if (CollectionUtil.isEmpty(page.getRecords())) {
            map.put("team", page);
        }
        List<SysUserVo> sysUserVos = BeanUtil.copyToList(page.getRecords(), SysUserVo.class);
        IPage<SysUserVo> result = query.build();
        result.setTotal(page.getTotal());
        result.setRecords(sysUserVos);
        map.put("team", result);
        return R.ok(map);
    }

    @GetMapping("/getTeam")
    public R<Map<String, Object>> getMyTeam(PageQuery query, Long userId) {
        Map<String, Object> map = new HashMap<>();
        //查询团队
        IPage<SysUser> page = userService.lambdaQuery().eq(SysUser::getSuperiorId, userId).page(query.build());
        if (CollectionUtil.isEmpty(page.getRecords())) {
            map.put("team", page);
        }
        List<SysUserVo> sysUserVos = BeanUtil.copyToList(page.getRecords(), SysUserVo.class);
        IPage<SysUserVo> result = query.build();
        result.setTotal(page.getTotal());
        result.setRecords(sysUserVos);
        map.put("team", result);
        return R.ok(map);
    }

}
